package com.hzlx.service;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.hzlx.bean.Order;
import com.hzlx.bean.OrderLineItem;
import com.hzlx.dao.OrderDao;
import com.hzlx.dao.OrderLineItemDao;
import com.hzlx.dto.*;
import io.seata.spring.annotation.GlobalTransactional;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.core.ParameterizedTypeReference;
import org.springframework.http.*;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;

import java.util.*;
import java.util.stream.Collectors;

@Service
@Slf4j
public class OrderService {
    @Resource RestTemplate restTemplate;
    @Resource OrderDao orderDao;
    @Resource OrderLineItemDao orderLineItemDao;
    @Resource ApplicationEventPublisher applicationEventPublisher;
    @GlobalTransactional // 全局事务
    public String create(OrderRequest orderRequest) {
        // 1、判断库存
        List<Map<String,Object>> skus = orderRequest.getOrderLineItemList()
                .stream()
                .map(orderLine->orderLine.getSku())
                .collect(Collectors.toList());
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_JSON);
        HttpEntity entity = new HttpEntity(skus, headers);
        ParameterizedTypeReference<ResultDto<List<InventoryResponse>>> pt = new ParameterizedTypeReference<>(){};
        ResponseEntity<ResultDto<List<InventoryResponse>>> result =
                restTemplate.exchange("http://inventory-service/api/inventory/isInStock",
                HttpMethod.POST,
                entity,
                pt);
        log.info("库存查询完毕!");
        // 如果所有商品都有库存
        if(result.getBody().getCode().equals("ok") &&
                result.getBody().getData().stream().allMatch(resp->resp.getQuantity()>0)){
            // 2、创建订单
            String orderNum = "O-" + UUID.randomUUID().toString();  // 自动生成订单号
            // 构建订单对象
            Order order = Order.builder()
                    .orderNumber(orderNum)
                    .createdTime(new Date())
                    .orderLineItemList(new ArrayList<>())
                    .ownerId(orderRequest.getOwnerId())
                    .build();
            orderDao.insert(order); // 添加订单
            log.info("订单{}-{}添加完毕！",orderNum, order.getId());
            orderRequest.getOrderLineItemList()
                    .stream()
                    .map(dto-> OrderLineItem.builder()
                            .sku(JSONObject.toJSONString(dto.getSku()))
                            .orderId(order.getId())
                            .quantity(dto.getQuantity())
                            .price(dto.getPrice())
                            .build())
                    .forEach(itemLine->{
                        orderLineItemDao.insert(itemLine);
                        log.info("详单{}添加成功！",itemLine.getSku());
                    });
            // 3、减库存
            List<InventoryRequest> list = orderRequest.getOrderLineItemList()
                    .stream()
                    .map(dto-> InventoryRequest.builder()
                            .sku(JSONObject.toJSONString(dto.getSku()))
                            .quantity(dto.getQuantity())
                            .build())
                    .collect(Collectors.toList());
            HttpHeaders inventoryHeaders = new HttpHeaders();
            inventoryHeaders.setContentType(MediaType.APPLICATION_JSON);
            HttpEntity inventoryEntity = new HttpEntity(list, inventoryHeaders);
            // 远程调用
            restTemplate.put("http://inventory-service/api/inventory",inventoryEntity);
            log.info("减库存成功！");
            // 4、异步通知
            applicationEventPublisher.publishEvent(orderNum);
            log.info("异步通知完毕！");
            return orderNum;
        }else {
            throw new IllegalArgumentException("库存不足！");
        }
    }

    public PageDto<OrderResponse> find(Integer ownerId, Integer page, Integer rows) {
        IPage<?> pageBean = new Page<>(page,rows);
        IPage<Order> pageResult = orderDao.selectPageVo(pageBean, ownerId);
        return PageDto.<OrderResponse>builder()
                .data(pageResult.getRecords().stream()
                        .map(order->OrderResponse.builder()
                        .id(order.getId().intValue())
                        .orderNumber(order.getOrderNumber())
                        .createTime(order.getCreatedTime())
                        .build()).collect(Collectors.toList()))
                .pages((int)pageResult.getPages()).build();
    }
}
